package com.ala4.oxcafe.boot.filter;

import com.ala4.oxcafe.boot.utils.ThreadMdcUtil;
import com.ala4.oxcafe.common.utils.text.StrUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 线程日志过滤器
 *
 * @author PING
 * @date 2024/1/18 22:36
 */
@Slf4j
@Order(Integer.MIN_VALUE)
@Component
public class ThreadMdcFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        if (servletRequest instanceof HttpServletRequest httpServletRequest) {
            String headerTraceId = httpServletRequest.getHeader(ThreadMdcUtil.HEADER_TRACE_ID);
            if (StrUtil.isNotEmpty(headerTraceId)) {
                ThreadMdcUtil.setTraceIdIfAbsent(headerTraceId);
            } else {
                ThreadMdcUtil.setTraceIdIfAbsent();
            }
        }
        // 这里一定要遭doFilter之前设置，因为在doFilter之后，response的状态已经是committed=true，如果是在doFilter之后设置，结果会正常返回，但是没有设置的header（注意浏览器会拿不到但是请求工具可以拿到）
        if (servletResponse instanceof HttpServletResponse httpServletResponse) {
            httpServletResponse.addHeader(ThreadMdcUtil.HEADER_TRACE_ID, ThreadMdcUtil.getTraceId());
        }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            ThreadMdcUtil.remove();
        }
    }
}
